/*************************************************************************
	> File Name:    byte_string.h
	> Author:       陈猛
	> Mail:         chen-meng@example.com
	> Created Time: 2019年09月26日 星期四 10时39分08秒
    > Description:  定义字符串处理类，都是使用浅拷贝的方式，如果是临时使用的字符，
                    一定要在最后一次使用后释放，不然就会造成内存泄露。
                    使用起来极度危险，不会用，就用标准模板库的std::string
 ************************************************************************/
#ifndef _BYTE_STRING_H_
#define _BYTE_STRING_H_

class ByteStringList;
/**
 * @brief The ByteString class
 * @note 用于管理字符串
 * @warning 当前管理的字符串，都是浅拷贝，字符串的内存空间不由当前类管理，
 *      需要释放必须主动调用clear，析构函数不做释放处理.
 */
class ByteString
{
public:
    ByteString();
    ByteString(const char *str, int size);
    ByteString(const char *str);
    //! 构造一个size大小的buffer, reserve用于取消默认构造
    ByteString(int size, int reserve);

    /**
     * @brief allocString
     * @param bstr [in]
     * @return 用户需要自己管理字串内存
     */
    static ByteString allocString(const ByteString &bstr);
    static ByteString allocLong(long i);
    static ByteString allocDouble(double i);
    //! 数据转换成字符串，返回的字符串不需要释放，字符存在一个静态变量中
    static ByteString numToString(bool i);
    static ByteString numToString(int i)
    {
        return numToString((long)i);
    }
    static ByteString numToString(unsigned int i)
    {
        return numToString((unsigned long)i);
    }
    static ByteString numToString(long i);
    static ByteString numToString(unsigned long i);

    static ByteString numToString(long long i);
    static ByteString numToString(unsigned long long i);

    static ByteString numToString(float i);
    static ByteString numToString(double i);
    static ByteString numToString(float i, const char *fmt);
    static ByteString numToString(double i, const char *fmt);

    /**
     * @brief concatStrings
     * @param first [in]
     * @param str0 [in]
     * @return 用户需要自己管理字串内存
     * @details 字串拼接
     */
    static ByteString concatStrings(const ByteString &first, const char *str0, ...);

    inline int   size()   const { return mLen; }
    inline char *string() const { return mString; }
    inline char *c_str()  const { return mString; }
    inline char *data()   const { return mString; }
    inline bool  isValid()const { return !!mString; }
    inline bool  empty()  const { return (0 == mLen || !mString || 0 == *mString) ? true : false; }

    void clear();
    void clear() const
    {
        const_cast<ByteString *>(this)->clear();
    }

    // 当前字符地址必须时new出来的，否则出错
    void append(ByteString const &str);
    void append(const ByteString &str) const
    {
        const_cast<ByteString *>(this)->append(str);
    }
    void append(const char *str, int len)
    {
        append(ByteString(str, len));
    }

    //! 当前尺寸小于size就重新分配内存,不设置mLen为size, 只是扩容
    void realloc(int size);
    void realloc(int size) const
    {
        const_cast<ByteString *>(this)->realloc(size);
    }
    //!从新设置数组大小,在末尾添加\0,只是修改了mLen
    void resize(int size);
    void resize(int size) const
    {
        const_cast<ByteString *>(this)->resize(size);
    }

    void swap(ByteString &str);
    void swap(ByteString &str) const
    {
        const_cast<ByteString *>(this)->swap(str);
    }

    unsigned long genHashValue() const;

    /**
     * @brief toInt/toDouble/toLong
     * @param def [in] 传递给返回值的默认值(-1)
     * @return 字符转数据
     */
    int    toInt(int def = -1);
    int    toInt(int def = -1) const
    {
        return const_cast<ByteString *>(this)->toInt(def);
    }

    unsigned int toUInt(unsigned int def = 0)
    {
        return (unsigned int)toInt(def);
    }
    int    toUInt(unsigned int def = 0) const;

    bool   toBool(bool def = false);
    bool   toBool(bool def = false) const
    {
        return const_cast<ByteString *>(this)->toBool(def);
    }
    double toDouble(double def = 0.0);    
    double toDouble(double def = 0.0) const
    {
        return const_cast<ByteString *>(this)->toDouble(def);
    }

    long   toLong(long def = -1);
    unsigned long toULong(unsigned long def = 0);
    long long toULongLong(long long def = 0);
    unsigned long long toLongLong(unsigned long long def = 0);

    bool operator==(const ByteString &str) const;
    bool operator!=(const ByteString &str) const;
    bool operator<(const ByteString &str) const;
    bool operator>(const ByteString &str) const;

    /**
     * @brief compare
     * @param str
     * @return this < str = 1 OR this > str = -1 OR str == this = 0
     */
    int  compare(const ByteString &str);
    int  compare(const ByteString &str) const
    {
        return const_cast<ByteString *>(this)->compare(str);
    } 
    int  ncompare(const ByteString &str);
    int  ncompare(const ByteString &str) const
    {
        return const_cast<ByteString *>(this)->ncompare(str);
    }

    /**
     * @brief find
     *  查找匹配，从头开始
     * @param str 需要查找的字符串
     * @param pos 查找的开始位置，默认从头开始
     * @return -1表示没有找到，>=0 表示找到的起始位置
     */
    int find(const ByteString &str, int pos = 0);
    int find(const ByteString &str, int pos = 0) const
    {
        return const_cast<ByteString *>(this)->find(str, pos);
    }
    /**
     * @brief find
     *  查找匹配，从头开始
     * @param ch 需要查找的字符串
     * @param pos 查找的开始位置，默认从头开始
     * @return -1表示没有找到，>=0 表示找到的起始位置
     */
    int find(int ch, int pos = 0);
    int find(int ch, int pos = 0) const
    {
        return const_cast<ByteString *>(this)->find(ch, pos);
    }

    /**
     * @brief rfind
     *  查找匹配，从末尾开始
     * @param str 需要查找的字符串
     * @param pos 用于返回搜索的字符索引(默认结束位置)。
     *  -1为最后的位置，-2为倒数第二个位置，依次类推
     *  正数：0 表示从第一个位置开始，但是是不合法的位置
     * @return -1表示没有找到，>=0 表示找到的起始位置
     */
    int rfind(const ByteString &str, int pos = -1);
    int rfind(const ByteString &str, int pos = -1) const
    {
        return const_cast<ByteString *>(this)->rfind(str, pos);
    }
    /**
     * @brief rfind
     *  查找匹配，从末尾开始
     * @param ch 需要查找的字符串
     * @param pos 用于返回搜索的字符索引(默认结束位置)。
     * @return -1表示没有找到，>=0 表示找到的起始位置
     */
    int rfind(int ch, int pos = -1);
    int rfind(int ch, int pos = -1) const
    {
        return const_cast<ByteString *>(this)->rfind(ch, pos);
    }

    //! @warning mString 地址必须在堆区（new）
    //! eg: "abc" + ByteString(); 错误的表示
    void operator+=(const ByteString &str) const
    {
        append(str);
    }
    ByteString operator+(const ByteString &str) const
    {
        append(str);
        return *this;
    }
    //! warning 之前必须判断是否越界
    char &operator[](int pos)
    {
        return *(mString+pos);
    }
    char &operator[](int pos) const
    {
        return *(mString+pos);
    }

    //! 字符转义，编码
    static void urlEncoding(const ByteString &query, ByteString &result, char percent='%');
    //! 字符转义，解码, 会修改query内存数据
    static void urlDecoding(ByteString &query, char percent='%');

    //! 返回utf8字符后续长度
    static int getUtf8Size(const unsigned char pInput);
    //! 返回合法的utf8字符，长度，用于截取前面合法的长度
    static int validUtf8Length(const char *data, int len);
    static int validUtf8Length(const ByteString &data) {
        return validUtf8Length(data.data(), data.size());
    }

private:
    char *mString;
    int   mLen;
    friend class ByteStringList;
};

#include <list>
class ByteStringList : public std::list<ByteString>
{
public:
    ByteStringList(const ByteString &str, char spilt = ',');

    bool contain(const ByteString &str);
private:
    friend class ByteString;
};


#endif // _BYTE_STRING_H_

